package cate.game.activity.dailylogin;

import cate.common.table.activity.dailylogin.item.DailyLoginActivityItemRow;
import cate.common.table.d.GDFunc;
import cate.common.table.d.GDOperation;
import cate.common.table.pay.PayItemRow;
import cate.common.util.GameResult;
import cate.game.activity.base.core.RoleActivitySingle;
import cate.game.activity.dailylogin.msg.DailyLoginActivityInfoResp;
import cate.game.activity.merge.msg.MergeLoginActivityInfoResp;
import cate.game.chat.ChatContentParam;
import cate.game.event.activity.BuyGiftEvent;
import cate.game.role.Role;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;

import java.util.*;

@NoteClass(value = "每日登陆活动")
public class DailyLoginSingle extends RoleActivitySingle {
    @NoteField(value = "档位")
    public Map<Integer, DailyLoginActivityLevel> levels;

    @Override
    public void initialize(Role role) {
        super.initialize(role);
        if (levels == null) {
            levels = new HashMap<>();
        }
        levels.values().forEach(levelPO -> levelPO.initialize(this));
    }

    @Override
    public void onEnter() {
        super.onEnter();
        levels.values().forEach(DailyLoginActivityLevel::onEnter);
    }

    @Override
    public void onRoleOpen() {
        levels.values().forEach(DailyLoginActivityLevel::onEnter);
    }

    @Override
    public void onRoleEnd() {
        if (levels != null) {
            levels.values().forEach(DailyLoginActivityLevel::clear);
        }
    }

    @Override
    public void initSend() {
        noticeUpdate();
    }

    @Override
    public void excelCheck() {
        Set<Integer> levelSet = getLevelSet();
        if (levelSet == null || levelSet.isEmpty()) {
            levels.clear();
            return;
        }
        levels.entrySet().removeIf(entry -> !levelSet.contains(entry.getKey()));
        for (int level : levelSet) {
            if (!levels.containsKey(level)) {
                DailyLoginActivityLevel levelPO = new DailyLoginActivityLevel(level);
                levelPO.initialize(this);
                levels.put(level, levelPO);
            }
        }
        levels.values().forEach(DailyLoginActivityLevel::excelCheck);
    }

    @Override
    public void onDaySpan(boolean silence) {
        super.onDaySpan(silence);
        levels.values().forEach(level -> level.onDaySpan(silence));
        if (!silence) {
            noticeUpdate();
        }
    }

    public void noticeUpdate() {
        switch (funcId()) {
            case GDFunc.NATURE_SEVEN_DAY_LOGIN:
            case GDFunc.ACT_SEVEN_DAY_LOGIN:
                role.sendNow(new DailyLoginActivityInfoResp(this));
                break;
            case GDFunc.MergeAct.MERGE_ACT_LOGIN:
                role.sendNow(new MergeLoginActivityInfoResp(this));
                break;
            default:
                break;
        }
    }

    /**
     * 获取指定奖励配置
     *
     * @param itemTid 奖励项ID
     */
    @JsonIgnore
    public DailyLoginActivityItemRow getItemConfig(int itemTid) {
        switch (funcId()) {
            case GDFunc.NATURE_SEVEN_DAY_LOGIN:
            case GDFunc.ACT_SEVEN_DAY_LOGIN:
                return role.getGame().table.sevenDayLoginActivity.item_sheet.get(itemTid);
            case GDFunc.MergeAct.MERGE_ACT_LOGIN:
                return role.getGame().table.mergeLogin.item_sheet.get(itemTid);
            default:
                return null;
        }
    }

    /**
     * 获取所有档位配置
     */
    @JsonIgnore
    public Set<Integer> getLevelSet() {
        Set<Integer> levelSet = new HashSet<>();
        switch (funcId()) {
            case GDFunc.NATURE_SEVEN_DAY_LOGIN:
            case GDFunc.ACT_SEVEN_DAY_LOGIN:
                for (DailyLoginActivityItemRow config : role.getGame().table.sevenDayLoginActivity.item_sheet.getList()) {
                    if (config.configTid == configTid()) {
                        levelSet.add(config.level);
                    }
                }
                break;
            case GDFunc.MergeAct.MERGE_ACT_LOGIN:
                for (DailyLoginActivityItemRow config : role.getGame().table.mergeLogin.item_sheet.getList()) {
                    if (config.configTid == configTid()) {
                        levelSet.add(config.level);
                    }
                }
                break;
            default:
                break;
        }
        return levelSet;
    }

    /**
     * 获取操作类型
     */
    @JsonIgnore
    public int getGDOperation() {
        switch (funcId()) {
            case GDFunc.ACT_SEVEN_DAY_LOGIN:
                return GDOperation.ACT_SEVEN_DAY_LOGIN;
            case GDFunc.NATURE_SEVEN_DAY_LOGIN:
                return GDOperation.NATURE_SEVEN_DAY_LOGIN;
            default:
                return GDOperation.NULL;
        }
    }

    public GameResult<Void> allowPay(PayItemRow pir) {
        int itemTid = pir.funcSubId;
        GameResult<Void> r = new GameResult<>();
        DailyLoginActivityItemRow itemConfig = getItemConfig(itemTid);
        if (itemConfig == null) {
            return r.fail("找不到配置");
        }
        DailyLoginActivityLevel levelPO = levels.get(itemConfig.level);
        if (levelPO == null) {
            return r.fail("找不到档位");
        }
        return levelPO.allowPay(itemTid);
    }

    public void onPaySuccess(PayItemRow pir) {
        int itemTid = pir.funcSubId;
        DailyLoginActivityItemRow itemConfig = getItemConfig(itemTid);
        if (itemConfig == null) {
            return;
        }
        DailyLoginActivityLevel levelPO = levels.get(itemConfig.level);
        if (levelPO == null) {
            return;
        }
        levelPO.provideReward(itemTid);
        if (itemConfig.lampId != 0) {
            List<ChatContentParam> params = new ArrayList<>();
            params.add(ChatContentParam.c(role.getBase().name));
            role.getGame().notice.lampOnline(role, itemConfig.lampId, params);
        }
        noticeUpdate();
        role.getGame().eventDispatcher.dispatchEvent(new BuyGiftEvent(role, funcId(), itemTid));
    }

    /**
     * 领取奖励
     *
     * @param itemTid 奖励项ID
     * @return 领取结果 无携带数据
     */
    public EcResult<DailyLoginSingle> receiveReward(int itemTid) {
        EcResult<DailyLoginSingle> r = new EcResult<>();
        r.data = this;
        DailyLoginActivityItemRow itemConfig = getItemConfig(itemTid);
        if (itemConfig == null) {
            return r.fail("找不到奖励");
        }
        DailyLoginActivityLevel levelPO = levels.get(itemConfig.level);
        if (levelPO == null) {
            return r.fail("找不到档位");
        }
        return levelPO.clientGetReward(itemTid);
    }
}
